package ru.niir.goodfil.audit.ui.extractors;

import ru.niir.goodfil.audit.domain.*;
import ru.niir.goodfil.audit.domain.enums.*;
import ru.niir.goodfil.audit.util.Assert;
import ru.niir.goodfil.excel.client.ValueExtractor;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author: Кирилл
 */
public class EventValueExtractor implements ValueExtractor {
    public Object extract(Object o) {
        Assert.notNull(o);

        if (o instanceof LoginEvent) {
            return extractLoginEventValue((LoginEvent) o);
        }
        if (o instanceof EntityEvent) {
            return extractEntityEventValue((EntityEvent) o);
        }
        if (o instanceof ExceptionEvent) {
            return extractExceptionEvent((ExceptionEvent) o);
        }
        if (o instanceof SettingModificationEvent) {
            return extractSettingModificationEvent((SettingModificationEvent) o);
        }
        if (o instanceof EnviromentIntegrityEvent) {
            return extractEnviromentIntegrityEvent((EnviromentIntegrityEvent) o);
        }
        if (o instanceof PersonalPriceEvent) {
            return extractPersonalPriceEvent((PersonalPriceEvent) o);
        }
        if (o instanceof PasswordChangeEvent) {
            return extractPasswordChangeEvent((PasswordChangeEvent) o);
        }
        if (o instanceof UserUIEvent) {
            return extractUserUIEvent((UserUIEvent) o);
        }
        if (o instanceof ClientUIEvent) {
            return extractClientUIEvent((ClientUIEvent) o);
        }
        if (o instanceof ClientC1NumChangeEvent) {
            return extractClientC1NumChangeEvent((ClientC1NumChangeEvent) o);
        }
        if (o instanceof ClientDebtChangeEvent) {
            return extractClientDebtChangeEvent((ClientDebtChangeEvent) o);
        }
        if (o instanceof ClientDeliveryInfoChangeEvent) {
            return extractClientDeliveryInfoChangeEvent((ClientDeliveryInfoChangeEvent) o);
        }
        if (o instanceof ClientPriceColumnChangeEvent) {
            return extractClientPriceColumnChangeEvent((ClientPriceColumnChangeEvent) o);
        }
        if (o instanceof OrderUIEvent) {
            return extractOrderUIEvent((OrderUIEvent) o);
        }
        if (o instanceof OrderItemUIEvent) {
            return extractOrderItemUIEvent((OrderItemUIEvent) o);
        }

        return "";
    }

    private Object extractOrderItemUIEvent(OrderItemUIEvent o) {
        if (o.getType() == OrderItemUIEventType.REMOVED) {
            return "Позиция " + o.getGoodCode() + " " + o.getCount() + " удалена из заказа " + o.getOrderId();
        }
        if (o.getType() == OrderItemUIEventType.COUNT_CHANGED) {
            return "Для позиции " + o.getGoodCode() + " заказа " + o.getOrderId() + " изменено количество: " + o.getCount();
        }
        if (o.getType() == OrderItemUIEventType.ADDED) {
            return "К заказу " + o.getOrderId() + " добавлена позиция " + o.getGoodCode() + " " + o.getCount() + "шт. со стоимостью " + o.getPrice();
        }
        if (o.getType() == OrderItemUIEventType.PRICED) {
            return "На позицию " + o.getGoodCode() + " " + o.getCount() + "шт. заказа " + o.getOrderId() + " установлена цена " + o.getPrice();
        }
        return "";
    }

    private Object extractOrderUIEvent(OrderUIEvent o) {
        if (o.getType() == OrderUIEventType.CREATED) {
            return "Заказ №" + o.getOrderId() + " на клиента " + o.getClientName() + " [" + o.getClientId() + "] (менеджер " + o.getManagerName() + " [" + o.getManagerId() + "]) СОЗДАН";
        }
        if (o.getType() == OrderUIEventType.CREATED_FROM_EXCEL) {
            return "Заказ №" + o.getOrderId() + " на клиента " + o.getClientName() + " [" + o.getClientId() + "] (менеджер " + o.getManagerName() + " [" + o.getManagerId() + "]) ЗАГРУЖЕН ИЗ EXCEL (стоимость: " + o.getOrderSum() + ")";
        }
        if (o.getType() == OrderUIEventType.ROLLBACKED) {
            return "Заказ №" + o.getOrderId() + " на клиента " + o.getClientName() + " [" + o.getClientId() + "] (менеджер " + o.getManagerName() + " [" + o.getManagerId() + "]) СБРОШЕН";
        }
        if (o.getType() == OrderUIEventType.SAVED) {
            return "Заказ №" + o.getOrderId() + " на клиента " + o.getClientName() + " [" + o.getClientId() + "] (менеджер " + o.getManagerName() + " [" + o.getManagerId() + "]) ОФОРМЛЕН (стоимость: " + o.getOrderSum() + ")";
        }
        if (o.getType() == OrderUIEventType.VALIDATED) {
            return "Заказ №" + o.getOrderId() + " на клиента " + o.getClientName() + " [" + o.getClientId() + "] (менеджер " + o.getManagerName() + " [" + o.getManagerId() + "]) СОГЛАСОВАН (стоимость: " + o.getOrderSum() + ")";
        }
        return "";
    }

    private Object extractClientPriceColumnChangeEvent(ClientPriceColumnChangeEvent o) {
        return "Для клиента " + o.getClientName() + " [" + o.getClientId() + "] изменена ценовая колонка для брэнда " + o.getBrandName() + " [" + o.getBrandId() + "] " + o.getOldColumnName() + " -> " + o.getNewColumnName();
    }

    private Object extractClientDeliveryInfoChangeEvent(ClientDeliveryInfoChangeEvent o) {
        return "Для клиента " + o.getClientName() + " [" + o.getClientId() + "] изменена информация о доставке.";
    }

    private Object extractClientDebtChangeEvent(ClientDebtChangeEvent o) {
        return "Долг клиента \"" + o.getClientName() + "\" [" + o.getClientId() + "] изменен. Долг по кассе " + o.getOldDebtCash() + " -> " + o.getNewDebtCash() + ". Долг по банку " + o.getOldDebtBank() + " -> " + o.getNewDebtBank();
    }

    private Object extractClientC1NumChangeEvent(ClientC1NumChangeEvent o) {
        return "Код 1С клиента \"" + o.getClientName() + "\" [" + o.getClientId() + "] изменен с \"" + o.getOldC1Num() + "\" на \"" + o.getNewC1Num() + "\"";
    }

    private Object extractClientUIEvent(ClientUIEvent o) {
        if (o.getCrud().equals(Crud.CREATE)) {
            return "Создание клиета " + o.getName();
        }
        if (o.getCrud().equals(Crud.UPDARE)) {
            return "Изменение клиета " + o.getName();
        }
        if (o.getCrud().equals(Crud.DELETE)) {
            return "Удаление клиета " + o.getName();
        }
        return null;
    }

    private Object extractUserUIEvent(UserUIEvent o) {
        if (o.getCrud().equals(Crud.CREATE)) {
            return "Создание пользователя " + o.getName();
        }
        if (o.getCrud().equals(Crud.UPDARE)) {
            return "Изменение пользователя " + o.getName();
        }
        if (o.getCrud().equals(Crud.DELETE)) {
            return "Удаление пользователя " + o.getName();
        }
        return "";
    }

    private String extractPasswordChangeEvent(PasswordChangeEvent event) {
        return "Новый пароль для пользователя \"" + event.getUserLogin() + "\" был отправлен по адресу \"" + event.getAddress() + "\"";
    }

    private final SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy");

    private String formantDate(Date date) {
        if (date == null) {
            return "null";
        } else {
            return sdf.format(date);
        }
    }

    private String extractPersonalPriceEvent(PersonalPriceEvent event) {
        StringBuilder sb = new StringBuilder();

        if (event.getCrud().equals(Crud.CREATE)) {
            sb.append("Установлена персональная цена на товар ");
            sb.append(event.getGoodCode() + " " + event.getGoodName() + " (" + event.getGoodId() + ") ");
            sb.append("для клиента " + event.getClientName() + " (" + event.getClientId() + "): " + event.getPrice() + " ");
            sb.append("с " + formantDate(event.getBegdate()) + " по " + formantDate(event.getEnddate()));
        }
        if (event.getCrud().equals(Crud.DELETE)) {
            sb.append("Удалена персональная цена на товар ");
            sb.append(event.getGoodCode() + " " + event.getGoodName() + " (" + event.getGoodId() + ") ");
            sb.append("для клиента " + event.getClientName() + " (" + event.getClientId() + "): " + event.getPrice() + " ");
            sb.append("с " + formantDate(event.getBegdate()) + " по " + formantDate(event.getEnddate()));
        }

        return sb.toString();
    }

    private String extractEnviromentIntegrityEvent(EnviromentIntegrityEvent event) {
        StringBuilder sb = new StringBuilder();
        sb.append("Система \"");
        if (event.getSubsystem().equals(EnviromentSubsystem.ARCHIVER)) {
            sb.append("АРХИВАТОР");
        }
        if (event.getSubsystem().equals(EnviromentSubsystem.MAILER)) {
            sb.append("РОБОТ РАССЫЛКИ");
        }
        if (event.getSubsystem().equals(EnviromentSubsystem.C1)) {
            sb.append("1C (на стороне 1С)");
        }
        if (event.getSubsystem().equals(EnviromentSubsystem.C1_INTEGRATION)) {
            sb.append("Интеграция с 1С (на стороне ИС)");
        }
        sb.append("\" ");
        if (event.getEvent().equals(IntegrityEvent.FOUND)) {
            sb.append(" обнаружена.");
        }
        if (event.getEvent().equals(IntegrityEvent.LOST)) {
            sb.append(" потеряна.");
        }
        return sb.toString();
    }

    private String extractSettingModificationEvent(SettingModificationEvent event) {
        return "Изменение настройки ИС " + event.getOptionKey() + ". Было: \"" + event.getOldOptionValue() + "\", стало \"" + event.getNewOptionValue() + "\".";
    }

    private String extractExceptionEvent(ExceptionEvent event) {
        return "Ошибка в ИС";
    }

    private String extractEntityEventValue(EntityEvent event) {
        StringBuilder sb = new StringBuilder();

        if (event.getCrud().equals(Crud.CREATE)) {
            sb.append("Создание ");
        }
        if (event.getCrud().equals(Crud.UPDARE)) {
            sb.append("Изменение ");
        }
        if (event.getCrud().equals(Crud.DELETE)) {
            sb.append("Удаление ");
        }

        if (event.getKlass().equals("ru.niir.goodfil.db.Order")) {
            sb.append("заказа");
        }
        if (event.getKlass().equals("ru.niir.goodfil.db.Client")) {
            sb.append("клиента");
        }

        return sb.toString();
    }

    private String extractLoginEventValue(LoginEvent event) {
        if (event.getAction().equals(LoginAction.LOGIN_ATTEMPT)) {
            return "Попытка входа";
        }
        if (event.getAction().equals(LoginAction.LOGIN_SUCCESS)) {
            return "Вход выполнен";
        }

        return EventValueExtractor.class.getSimpleName();
    }
}
